Merge test branch to main#337
Conversation
the examples/ fixtures gained rendered screenshots in #290 but the top-level readme never pointed at them. add a one-line nudge from the 30-second tour so a reader can see what the cli returns before installing.
render.py resolved `vouch` off PATH first, so a stale global install shadowing the venv would render every shot against the wrong build and silently overwrite the committed images. prefer the vouch next to the running interpreter (the venv's editable build); fall back to PATH only when none exists. the guard test now passes without activating the venv.
docs(examples): surface screenshots in readme, harden render resolution
add docs/tutorials/ — an index plus four diátaxis walkthroughs (build your first knowledge base, give a coding agent a reviewed memory, share a kb via bundles, edit a kb in obsidian). every command was run end-to-end against the cli before it went in, so the walkthroughs only cover verified behaviour (including the real forbidden_self_approval review gate). feature the native one-line wire-up `claude mcp add vouch -- vouch serve` in getting-started step 6, and add a "how a host talks to vouch" section to docs/transports.md describing the stdio mcp path end to end — spawn, handshake, tool call, review gate, _meta sidebars, server-to-client push. fix the read-sidebar guidance in claude.md: the per-tool read sidebar is _meta.vouch_salience (salience.py, attached by kb_context), not vouch_hot_memory — that key is written only by the openclaw context engine's assemble().
docs: add tutorials, host-comms walkthrough, one-line mcp install
`vouch pending` — and every bulk `list_*` path — crashed with a yaml ReaderError when a single proposal file held a control character: one unreadable file took down the whole listing. add a `_load_or_skip` helper that logs a warning and skips the bad file instead of aborting, applied across proposals, claims, entities, relations, evidence, sessions, sources. the control character traces back to vouch's own file i/o relying on the locale default encoding: on a non-utf-8 locale (e.g. latin-1) read_text / write_text / open mangle non-ascii into raw bytes the yaml loader rejects, and can even crash on write. pin encoding="utf-8" on all text-mode pathlib i/o under src/vouch. adds regression tests for the resilient listing.
fix(storage): survive unreadable artifact files and pin utf-8 i/o
update package version across pyproject.toml, src/vouch/__init__.py, openclaw.plugin.json, and SPEC.md examples to reflect 1.0.0 stable release.
Chore/version 1.0.0
feat: claude code session auto-capture + approved-knowledge recall
design: automatic finalization of old buffers on sessionstart, and current session on window close. plan: 8-task breakdown covering capture.py functions, cli command, adapter hooks, comprehensive unit tests, integration test, and documentation.
implement is_stale_buffer() to check file age, and finalize_all_except() to bulk-finalize capture buffers older than a threshold. this enables sessionstart cleanup of orphaned buffers from previous sessions. includes 9 unit tests covering single/multiple buffers, age boundaries, and current session exclusion.
new command finalizes all capture buffers except the given session, if they are older than max_age_seconds (default 3600s). silently succeeds if no kb found. used by sessionstart hook to clean up orphaned buffers from previous sessions. includes 3 unit tests covering option parsing, env fallback, and graceful degradation.
run 'vouch capture finalize-all' as the first sessionstart hook to clean up orphaned buffers from previous sessions before banner and recall commands. ensures old sessions are finalized automatically on next session start.
add comment to sessionstart hook explaining that current session finalization happens on next session start (fallback behavior when windowclose event is not supported by the vs code extension).
add section describing how capture works, configuration options, and the fallback behavior if windowclose event is not available.
verify that old buffers are cleaned up on new session start and current session is finalized on window close (or manual finalize), resulting in two separate proposals.
…rigin when finalize_all_except() cleans up orphaned buffers, those old sessions have unknown origin (no cwd), so we should not attribute the current working directory's git diff to them. this prevents data corruption where old sessions' summaries get current repo changes, and avoids spurious proposals that cross min_observations due to misattributed file counts. added explicit cwd check: if cwd is None (unknown origin), skip git changes. normal finalize calls with explicit cwd still get git context. also fix typo: unfinalzed -> unfinalized in adapter README.
feat(capture): automatic session finalization on sessionstart and close
adds kb.detect_themes (read-only cluster detector) and kb.propose_theme (routes synthesis pages through the review gate). scoring is deterministic — entity pair co-occurrence across sessions, weighted by log(1 + claim_count). registered on all four surfaces (mcp, jsonl, cli, capabilities). the cli exposes `vouch detect-themes` with --propose for one-shot propose-all. adds THEME to the PageType enum so theme pages pass the page-kind gate. deduplication prevents re-proposing clusters that already have pending or approved theme pages. closes #311
…utput - config reader now type-checks every value and falls back to defaults on malformed input (mirrors salience.reflex_cfg pattern) - dedup in detect_themes now compares on the resolvable entity subset so it stays consistent with what propose_theme actually stores - --propose --json no longer interleaves human-readable lines on stdout - adds changelog entry under [unreleased]
feat(themes): cross-session pattern detection via entity co-occurrence
the benchmark suite was implemented but unrunnable out of the box: pytest-benchmark wasn't in the [dev] extras, and the bench_*.py filenames don't match pytest's default python_files glob, so the documented invocation collected zero tests. - add pytest-benchmark to the [dev] optional-dependencies - add a `make bench` target that folds in the python_files override - record the first baseline (medians at 1k/10k) in benchmarks/README.md and flip its status from "not implemented yet" to implemented - gitignore the bench.json / .benchmarks run artifacts
# Conflicts: # Makefile
chore(bench): wire make bench, add pytest-benchmark, record baseline
lead the readme with session auto-capture — the feature that stops each new agent session from re-doing the last one's work. - banner.svg: add a "sessions capture themselves" on-ramp that funnels into the review gate; swap the approve/reject text labels for icons; refresh the example date and kb panel; add a self-capturing pill. - gittensor.md + readme gittensor section: reframe from "cited record of the subnet's scoring rules" to a real miner workflow — capture what a session learns about a target repo, approve it, recall it next session so the investigation happens once. grounded in the real sn74 loop (merged prs, repo allocation, a shuffling whitelist). - demo.gif/tape + example-session.md: the auto-capture walkthrough. - .claude/settings.json + commands: reference capture hooks and the four vouch slash commands. settings.local.json intentionally omitted.
…miner docs: redraw hero banner + reframe gittensor around the miner workflow
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (72)
📝 WalkthroughWalkthroughThis PR adds automatic Claude Code session capture (observe/finalize/recall) with a review gate, cross-session theme detection/proposal, JSON-merge install support for adapter settings, UTF-8 encoding hardening across config/artifact I/O, resilient bulk listing that skips corrupt files, benchmarking infrastructure, version bumps to 1.0.0, and extensive new documentation/tutorials. ChangesSession Auto-Capture & Recall
Cross-Session Theme Detection
Claude Adapter JSON-Merge Install
UTF-8 Encoding Hardening & Storage Resilience
Benchmarking Infrastructure
Documentation, Version Bumps, and Claude Commands
Estimated code review effort: 5 (Critical) | ~150 minutes Sequence Diagram(s)sequenceDiagram
participant Hook as ClaudeHook
participant CLI as vouch_cli
participant Capture as capture_module
participant Store as KBStore
Hook->>CLI: capture observe (tool payload)
CLI->>Capture: observe(session_id, tool, summary)
Capture->>Store: append JSONL buffer
Hook->>CLI: capture finalize (SessionEnd)
CLI->>Capture: finalize(session_id, cwd)
Capture->>Capture: build_summary_body()
Capture->>Store: propose_page() PENDING
Capture->>Store: delete buffer
Hook->>CLI: recall (SessionStart)
CLI->>Store: build_digest()
Store-->>Hook: approved claims/pages digest
sequenceDiagram
participant Client
participant Server as MCP_Server
participant Themes as themes_module
participant Store as KBStore
Client->>Server: kb_detect_themes()
Server->>Themes: detect_themes(store)
Themes-->>Server: DetectResult clusters
Client->>Server: kb_propose_theme(cluster)
Server->>Themes: propose_theme(store, cluster)
Themes->>Store: propose_page() PENDING
Themes-->>Server: proposal_id
Possibly related issues
Possibly related PRs
Suggested labels: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR, despite its minimal title ("Merge test branch to main") and empty description template, is a large feature drop that adds three major runtime capabilities to vouch and performs a 0.0.1 → 1.0.0 version bump. It introduces auto-capture of Claude Code sessions (capture.py + hooks), a session-start recall digest (recall.py), and cross-session theme detection (themes.py) exposed as two new kb.* methods (kb.detect_themes, kb.propose_theme) plus a new built-in PageType.THEME. It also sweeps encoding="utf-8" across text I/O, adds _load_or_skip resilience to bulk storage listings, and teaches the install adapter to deep-merge .claude/settings.json.
Note: the AGENTS.md hard rules state that surface changes (new kb.* methods, on-disk layout like .vouch/captures/, new page kinds) require an accepted VEP, and no matching proposal appears in proposals/. Combined with the empty PR description and the major version jump, the change set warrants human review before merge.
Changes:
- New features: session auto-capture, session-start recall digest, and cross-session theme detection with two new
kb.*methods, CLI commands, config namespaces, and Claude Code hook wiring. - Robustness/consistency: UTF-8 encoding pinned across text I/O,
_load_or_skipfor unreadable YAML in bulk listings, and idempotent JSON merge for adapter settings. - Release metadata: version bumped to
1.0.0across__init__.py,pyproject.toml,SPEC.md,openclaw.plugin.json, plus README/tutorial/CHANGELOG updates.
Reviewed changes
Copilot reviewed 71 out of 74 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vouch/capture.py | New auto-capture module; config read at line 44 misses encoding="utf-8". |
| src/vouch/recall.py | New recall-digest module; correctly pins UTF-8 (reference for the convention). |
| src/vouch/themes.py | New theme-detection module; config read at line 65 misses encoding="utf-8". |
| src/vouch/cli.py | Adds capture/recall/detect-themes commands; mangled comment at 3008 and a --json stdout leak at 1992-1994. |
| src/vouch/server.py | Registers kb_detect_themes / kb_propose_theme MCP tools. |
| src/vouch/jsonl_server.py | Adds theme JSONL handlers; lacks envelope-shape tests for the new methods. |
| src/vouch/capabilities.py | Appends the two new theme methods to METHODS. |
| src/vouch/storage.py | Adds _load_or_skip resilience, capture starter config, and gitignore for captures. |
| src/vouch/install_adapter.py | Adds idempotent json_merge for .claude/settings.json. |
| src/vouch/models.py | Adds PageType.THEME built-in page kind. |
| src/vouch/init.py | Version bump to 1.0.0, contradicting README's "pre-1.0 alpha" note. |
| pyproject.toml / SPEC.md / openclaw.plugin.json | Version metadata bumped to 1.0.0; adds pytest-benchmark. |
| adapters/claude-code/* | Wires capture/recall/finalize hooks into settings; manifest marks settings for merge. |
| Makefile / benchmarks/* / scripts/* | Adds bench, smoke-capture, smoke-recall targets and supporting scripts. |
| tests/test_capture.py, tests/test_recall.py, tests/test_themes.py, tests/test_install_adapter.py, tests/test_storage.py | New/updated tests for the added behavior (theme JSONL/MCP/CLI surface untested). |
| README.md / docs / CHANGELOG.md | Documentation and changelog updates for the new features. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if open_browser and is_loopback: | ||
| # Lazy-import webbrowser; some CI envs (headless) don't have a default | ||
| # browser configured and webbrowser.open() returns False rather than | ||
| # browser configured and webbrowser.open(encoding="utf-8") returns False rather than |
| def load_config(store: KBStore) -> CaptureConfig: | ||
| """Read ``capture:`` from config.yaml; fall back to defaults.""" | ||
| try: | ||
| loaded = yaml.safe_load(store.config_path.read_text()) |
| and falls back to its default rather than crashing on malformed input. | ||
| """ | ||
| try: | ||
| raw = yaml.safe_load(store.config_path.read_text()) |
| """vouch — git-native, review-gated knowledge base for LLM agents.""" | ||
|
|
||
| __version__ = "0.0.1" | ||
| __version__ = "1.0.0" |
| "kb.detect_themes": _h_detect_themes, | ||
| "kb.propose_theme": _h_propose_theme, |
| if not result.clusters: | ||
| click.echo("no themes detected") | ||
| return |
What changed
Why
What might break
VEP
Tests
make checkpasses locally (lint + mypy + pytest)CHANGELOG.mdupdated under## [Unreleased]Summary by CodeRabbit
New Features
Bug Fixes